//
//  KqOssManager.m
//  Pods
//
//  Created by wtb on 2023/3/9.
//

#import "KqOssManager.h"
#import <AliyunOSSiOS/OSSService.h>
#import "KqImageTool.h"
#import "KqTool.h"

static KqOssManager *ossManager;
@interface KqOssManager()
@property(nonatomic,copy) NSString *bucketName;
@property(nonatomic,strong) NSMutableDictionary *tasks;
@end
@implementation KqOssManager
{
    OSSClient *client;
}

+(instancetype)defaultKqOssManager{
    if (!ossManager) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            ossManager = [[KqOssManager alloc] init];
            ossManager.bucketName = @"gofactory";
            ossManager.tasks = [NSMutableDictionary dictionary];
        });
    }
    return ossManager;
}


-(void)initOSSClient{
    id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:[self getOAK] secretKey:[self getOSK]];
    OSSClientConfiguration * conf = [OSSClientConfiguration new];
    conf.maxRetryCount = 2; // 网络请求遇到异常失败后的重试次数
    conf.timeoutIntervalForRequest = 15; // 网络请求的超时时间
    client = [[OSSClient alloc] initWithEndpoint:[self getOEP] credentialProvider:credential clientConfiguration:conf];
}


-(NSString *)getOAK{
    Class class = NSClassFromString(@"GFUserManager");
    id user = [[class alloc] init];
    if ([user respondsToSelector:@selector(getOAK)]) {
        NSString *oak = [user performSelector:@selector(getOAK)];
        return oak;
    }
    return @"";
}

-(NSString *)getOSK{
    Class class = NSClassFromString(@"GFUserManager");
    id user = [[class alloc] init];
    if ([user respondsToSelector:@selector(getOSK)]) {
        NSString *osk = [user performSelector:@selector(getOSK)];
        return osk;
    }
    return @"";
}

-(NSString *)getOEP{
    Class class = NSClassFromString(@"GFUserManager");
    id user = [[class alloc] init];
    if ([user respondsToSelector:@selector(getOEP)]) {
        return [user performSelector:@selector(getOEP)];
    }
    return @"";
}

-(void)setOssBucketNameFromEnv:(BOOL)isRelease{
    if (!isRelease) {
        self.bucketName = @"gofactory4test";
    }else{
        self.bucketName = @"gofactory";
    }
}

-(void)downLoadImage:(NSString *)objectKey picWidth:(int)width picHeight:(int)height tag:(NSString *)tag callback:(void(^)(NSDictionary *uri))callback{
    OSSGetObjectRequest *getRequest = [OSSGetObjectRequest new];

    getRequest.bucketName = self.bucketName;
    
    getRequest.objectKey = objectKey;
    
    if (width > 0 && height > 0) {
        getRequest.xOssProcess = [NSString stringWithFormat:@"image/resize,m_fixed,w_%d,h_%d",width,height];
    }
    
    OSSTask *task = [client getObject:getRequest];
    if (tag && tag.length > 0) {
        [self.tasks setValue:getRequest forKey:tag];
    }
    __weak __typeof(self)weakSelf = self;
    [task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
        OSSGetObjectResult *result = task.result;
        if (tag && tag.length > 0) {
            [weakSelf.tasks removeObjectForKey:tag];
        }
        if (!task.error) {
            NSData *imgData = result.downloadedData;
            NSMutableDictionary *objectMeta = [NSMutableDictionary dictionary];
            NSString *type = [KqImageTool kqImageTypeWithData:imgData];
            if ([type isEqualToString:@"gif"]) {
                callback(nil);
            }
            
            //图片大小
            NSUInteger size = imgData.length;
            [objectMeta setValue:[NSString stringWithFormat:@"image/%@",type] forKey:@"Content-Type"];
            [objectMeta setValue:[NSNumber numberWithInteger:size] forKey:@"Content-Length"];
            NSString *fileName = [NSString stringWithFormat:@"%@",[KqTool stringToMd5:[NSString stringWithFormat:@"%@_%d_%d",objectKey,width,height]]];
            NSDictionary *uri = [KqOssManager getUriWithFileData:imgData objectMeta:objectMeta fileName:fileName];

            callback(uri);
        }else{
            callback(nil);
        }
        return nil;
    }];
}

-(void)uploadImage:(NSData *)imageData objectKey:(NSString *)objectKey callback:(void (^)(BOOL))callback{
    if (!imageData) {
        callback(NO);
        return;
    }
    OSSPutObjectRequest *putRequest = [OSSPutObjectRequest new];
    putRequest.bucketName = self.bucketName;
    putRequest.objectKey = objectKey;
    putRequest.uploadingData = imageData;
    OSSTask * task = [client putObject:putRequest];
    [task continueWithBlock:^id(OSSTask *task) {
        if (!task.error) {
            callback(YES);
        }else{
            callback(NO);
        }
        return nil;
    }];
}

-(void)uploadFile:(NSData *)fileData objectKey:(NSString *)objectKey progress:(void (^)(int64_t, int64_t, int64_t))progressCallback tag:(NSString *)tag callback:(void (^)(BOOL))callback{
    if (!fileData) {
        callback(NO);
        return;
    }
    OSSPutObjectRequest *putRequest = [OSSPutObjectRequest new];
    putRequest.bucketName = self.bucketName;
    putRequest.objectKey = objectKey;
    putRequest.uploadingData = fileData;
    putRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        progressCallback(bytesSent,totalBytesSent,totalBytesExpectedToSend);
    };
    OSSTask * task = [client putObject:putRequest];
    
    if (tag && tag.length > 0) {
        [self.tasks setValue:putRequest forKey:tag];
    }
    __weak __typeof(self)weakSelf = self;
    [task continueWithBlock:^id(OSSTask *task) {
        if (tag && tag.length > 0) {
            [weakSelf.tasks removeObjectForKey:tag];
        }
        if (!task.error) {
            callback(YES);
        }else{
            callback(NO);
        }
        return nil;
    }];
}

//-(void)uploadObjectAsyncWith:(NSData *)uploadData
//                   objectKey:(NSString *)objectKey
//                    callback:(void(^)(BOOL success))callback{
//    if (!uploadData) {
//        callback(GFOSSPutFail);
//        return;
//    }
//    OSSPutObjectRequest *putRequest = [OSSPutObjectRequest new];
//
//    putRequest.bucketName = [self getBucketName];
//
//    putRequest.objectKey = objectKey;
//    putRequest.uploadingData = uploadData;
//
//    OSSTask * task = [client putObject:putRequest];
//    [task continueWithBlock:^id(OSSTask *task) {
//        if (!task.error) {
//            callback(YES);
//        } else {
//            callback(NO);
//        }
//        return nil;
//    }];
//}

+(NSDictionary *)getUriWithFileData:(NSData *)data objectMeta:(NSDictionary *)objectMeta fileName:(NSString *)fileName{
//    NSString *base64 = [KqTool stringToMd5:[data base64EncodedStringWithOptions:0]];
    //文件大小
    NSNumber *fileSize = [objectMeta objectForKey:@"Content-Length"];
    //文件类型
    NSString *type = [objectMeta objectForKey:@"Content-Type"];
    
//    NSString *fileName = [NSString stringWithFormat:@"%@.%@",base64,type];
//    if ([type containsString:@"/"]) {
//        NSString *fileType = [[type componentsSeparatedByString:@"/"] lastObject];
//        fileName = [NSString stringWithFormat:@"%@.%@",base64,fileType];
//    }
    NSString *filePath = [KqTool getTmpImagePath:fileName folderName:@"kq"];
    BOOL success = [data writeToFile:filePath atomically:YES];
    if(success){
        NSLog(@"filePath_write_cache:%@",filePath);
    }
    NSMutableDictionary *uri = [NSMutableDictionary dictionary];
    [uri setValue:filePath forKey:@"filePath"];
    [uri setValue:fileSize forKey:@"fileSize"];
    [uri setValue:type forKey:@"fileMime"];
    [uri setValue:fileName forKey:@"fileName"];
    return uri;
}

+(void)cancel:(NSString *)tag{
    if (tag && tag.length > 3) {
        KqOssManager *oss = [KqOssManager defaultKqOssManager];
        if ([oss.tasks objectForKey:tag]) {
            OSSGetObjectRequest *request = (OSSGetObjectRequest *)[oss.tasks objectForKey:tag];
            [request cancel];
        }
    }
}

+(void)deleteImage:(NSString *)objectKey callback:(void(^)(BOOL success))callback{
    if (!objectKey) {
        return;
    }
    KqOssManager *oss = [KqOssManager defaultKqOssManager];
    OSSDeleteObjectRequest *delete = [OSSDeleteObjectRequest new];
    delete.bucketName = oss.bucketName;
    delete.objectKey = objectKey;
    OSSTask *task = [oss->client deleteObject:delete];
    [task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
        if (!task.error) {
            callback(YES);
        }else{
            callback(NO);
        }
        return nil;
    }];
}
@end
